fn number() -> i32 {
    8
}

// Two i32s will enter the function. We will call them number_one and number_two.
fn multiply_and_print(number_one: i32, number_two: i32) {
    let result = number_one * number_two;
    println!("{} times {} is {}", number_one, number_two, result);
}

fn multiply(number_one: i32, number_two: i32) -> i32 {
    let result = number_one * number_two;
    println!("{} times {} is {}", number_one, number_two, result);
    result // this is the i32 that we return
}

fn main() {
    {
        println!("Hello, world!");
        println!("Hello, world number {}!", 8);
        println!("Hello, world numbers {} and {}!", 8, 9);
        println!("Hello, world number {}!", number());
    }

    println!();

    {
        // We can give the numbers directly.
        multiply_and_print(8, 9);
        // Or we can declare two variables and put them in the function.
        let some_number = 10;
        let some_other_number = 2;
        multiply_and_print(some_number, some_other_number);

        // We used multiply() to print and to give the result to multiply_result.
        let multiply_result = multiply(8, 9);
        println!("Result: {}", multiply_result);
    }

    println!();

    {
        let my_number = {
            let second_number = 8;
            // No semicolon, so the code block returns 8 + 9.
            // It works just like a function.
            second_number + 9
        };

        println!("My number is: {}", my_number);
    }

    #[allow(clippy::let_unit_value)]
    {
        let my_number = {
            // Declare second_number, add 9 to second_number but we didn't
            // return it!
            let second_number = 8;
            let _ = second_number + 9;
            // second_number dies now.
        };

        // my_number is ().
        println!("My number is: {:?}", my_number);
    }
}
